import logging
import random
import numpy as np

from util.util_log import setup_logging
from util.util_csv import save_csv
from util.util_image import save_img, save_img_xyz, save_line_chart
from util.util_ris_pattern import phase_2_bit, phase_2_pattern, phase_2_pattern_xyz_fft, phase_2_pattern_xyz, \
    nRow, point_2_phase


# 配置日志，默认打印到控制台，也可以设置打印到文件
setup_logging()
# setup_logging(log_file="../../files/logs/log_multi_beam_PS.log")
# 获取日志记录器并记录日志
logger = logging.getLogger("[RIS-multi-beam-PS-1bit]")


def point_2_phase_pattern(theta0, phi0, bit_num):
    phase = point_2_phase(theta0, phi0)
    phase = np.rad2deg(phase)
    phaseBit, phaseBitDeg = phase_2_bit(phase, bit_num)
    phaseBit = np.deg2rad(phaseBitDeg)
    pattern, x, y = phase_2_pattern_xyz_fft(phaseBit)
    pattern_db = np.abs(pattern) / np.max(np.max(np.abs(pattern)))
    return phase, phaseBit, pattern, pattern_db, x, y


def mix_patterns(patterns):
    # 确保输入的是 NumPy 数组列表
    if not all(isinstance(p, np.ndarray) for p in patterns):
        raise ValueError("All inputs must be of type np.ndarray.")
    # 确保所有输入数组具有相同的形状
    if not all(p.shape == patterns[0].shape for p in patterns):
        raise ValueError("All input arrays must have the same shape.")
    # 将所有数组堆叠成一个三维数组，便于后续处理
    stacked_patterns = np.stack(patterns)
    # 找出每个位置上所有数组中小于0.5的所有值
    less_than_half = stacked_patterns < 0.5
    # 判断是否所有数组在该位置上的值都小于0.5
    all_less_than_half = np.all(less_than_half, axis=0)
    # 如果所有值都小于0.5，选择这些值中的最小值
    min_values = np.min(stacked_patterns, axis=0)
    # 如果所有值都不小于0.5，选择这些值中的最大值
    max_values = np.max(stacked_patterns, axis=0)
    # 根据条件生成最终的pattern_mix_target
    pattern_mix_target = np.where(all_less_than_half, min_values, max_values)
    #
    return pattern_mix_target


# ============================================= 遗传算法 ===========================================
class RISGeneticAlgorithm():
    __bit_num = 0       # 比特数
    __beam_num = 0      # 波束数

    def __init__(self, bit_num, beam_num, population_size=50, num_generations=100, num_parents=10, mutation_rate=0.1):
        # 初始化阵列相关
        self.__bit_num = bit_num
        self.__beam_num = beam_num
        # 初始化遗传算法相关
        self.population_size = population_size
        self.num_generations = num_generations
        self.num_parents = num_parents
        self.mutation_rate = mutation_rate
        self.population = None
        self.best_individual = None
        self.best_fitness = float('inf')
        self.best_fitness_history = []      # 保存每一代的最佳适应度值
        self.best_individual_history = []   # 保存每一代的最佳适应度值的个体

    def __calculate_ssd(self, pattern_mix_db, pattern_target_db):
        # 计算差值
        diff = pattern_mix_db - pattern_target_db
        # 计算差值的平方
        squared_diff = diff ** 2
        # 将所有平方差值相加
        ssd = np.sum(squared_diff)
        return ssd

    def fitness(self, phase_mix):
        # 相位转换 X bit
        phaseBit_mix, phaseBitDeg_mix = phase_2_bit(phase_mix, self.__bit_num)
        # 计算phase_mix的方向图
        phaseBit_mix = np.deg2rad(phaseBitDeg_mix)
        patternBit_mix, x, y = phase_2_pattern_xyz_fft(phaseBit_mix)    # FFT法计算, 快速
        # 计算码阵方向图的和目标方向图的差
        patternBit_mix_db = np.abs(patternBit_mix) / np.max(np.max(np.abs(patternBit_mix)))
        ssd = self.__calculate_ssd(patternBit_mix_db, self.pattern_target_db)
        return ssd

    # def fitness(self, cluster_init):
    #     list_sum = []
    #     for datas in cluster_init:
    #         sum = 0
    #         for data in datas:
    #             sum += data
    #         list_sum.append(sum)
    #     fit = 0
    #     for sum in list_sum:
    #         fit += sum ** 2
    #     return -fit

    def initialize_population(self, row, col):
        """初始化种群"""
        self.population = [np.random.uniform(low=-180.0, high=180.0, size=(row, col))] * self.population_size

    def selection(self):
        """选择操作"""
        fitness_scores = [self.fitness(individual) for individual in self.population]
        sorted_indices = np.argsort(fitness_scores)  # 从低到高排序
        selected_parents = [self.population[i] for i in sorted_indices[:self.num_parents]]
        # 获取选中的父代个体对应的适应度值
        selected_fitness_scores = [fitness_scores[i] for i in sorted_indices[:self.num_parents]]
        return selected_parents, selected_fitness_scores

    def crossover(self, parents, offspring_size):
        """交叉操作"""
        offspring = []
        for _ in range(offspring_size):
            parent1, parent2 = random.sample(parents, 2)
            parent1 = np.array(parent1)
            parent2 = np.array(parent2)
            # 获取数组的形状
            shape = parent1.shape
            # 将 parent1 和 parent2 扁平化为一维数组
            flat_parent1 = parent1.flatten()
            flat_parent2 = parent2.flatten()
            # 随机选择一个切割位置
            cut_point = random.randint(0, len(flat_parent1))
            # 生成子代
            child = np.concatenate((flat_parent1[:cut_point], flat_parent2[cut_point:]))
            # 将子代重新塑形为原始的二维数组形状
            child = child.reshape(shape)
            child = child.tolist()
            #
            offspring.append(np.array(child))
        return offspring

    def mutation(self, offspring):
        """变异操作"""
        for individual in offspring:
            if random.random() < self.mutation_rate:
                # 获取数组的数量和长度
                num_clusters, array_length = individual.shape
                # 生成一个与 individual 形状相同的随机数数组
                random_values = np.random.uniform(-180, 180, (num_clusters, array_length))
                # 决定哪些元素需要变异
                mask = np.random.rand(num_clusters, array_length) < self.mutation_rate
                # 应用变异
                individual[mask] = random_values[mask]
        return offspring

    def run(self, row, col, pattern_mix_db_target):
        logger.info("population_size=%d, num_generations=%d, num_parents=%d, mutation_rate=%d"
                    % (self.population_size, self.num_generations, self.num_parents, self.mutation_rate))
        # """运行遗传算法 -- 初始化阶段"""
        self.initialize_population(row, col)
        # """初始化返回值"""
        self.pattern_target_db = pattern_mix_db_target
        self.best_individual = self.population[0]
        self.best_fitness = self.fitness(self.population[0])
        self.best_fitness_history = []
        self.best_individual_history = []
        # """运行遗传算法 -- 搜索阶段"""
        for generation in range(self.num_generations):
            # 选择操作
            selected_parents, selected_fitness_scores = self.selection()
            # 交换操作
            offspring = self.crossover(selected_parents, self.population_size - self.num_parents)
            # 变异操作
            offspring = self.mutation(offspring)
            # 计算后代的适应度值
            offspring_fitness_scores = [self.fitness(individual) for individual in offspring]
            # 更新种群
            self.population = selected_parents + offspring
            # 合并父代和后代的适应度值
            all_fitness_scores = selected_fitness_scores + offspring_fitness_scores
            #
            # 找到当前代的最佳个体
            this_best_index = np.argmax(all_fitness_scores)  # 找到最佳适应度值的索引
            if this_best_index < len(selected_parents):
                this_best_individual = selected_parents[this_best_index]  # 最佳个体来自父代
            else:
                this_best_individual = offspring[this_best_index - len(selected_parents)]  # 最佳个体来自后代
            this_best_fitness = all_fitness_scores[this_best_index]  # 最佳适应度值
            #
            # 更新最佳适应度
            if this_best_fitness < self.best_fitness:
                self.best_fitness = this_best_fitness
                self.best_individual = this_best_individual
            # 记录最佳适应度曲线
            self.best_fitness_history.append(self.best_fitness)
            self.best_individual_history.append(self.best_individual)
            #
            # logger.info("generation=%d: self.best_fitness=%f, self.best_individual:%s"
            #             % (generation, self.best_fitness, self.best_individual))
            logger.info("generation=%d: self.best_fitness=%f" % (generation, self.best_fitness))
        return self.best_individual, self.best_fitness, self.best_fitness_history, self.best_individual_history


# ============================================= 主函数 ====================================
# GA 核心算法 -- 双波束
def ga_beam_2(pattern_mix_db_target, bit_num):
    # 遗传算法(GA)寻找最优的phaseBit_mix
    ga = RISGeneticAlgorithm(bit_num, 2, 50, 500, 10, 0.1)
    best_individual, best_fitness, best_fitness_history, best_individual_history \
        = ga.run(nRow, nRow, pattern_mix_db_target)
    # logger.info("best_individual:%s" % (best_individual))
    logger.info("Best Fitness=%f" % (best_fitness))
    #
    return best_individual, best_fitness, best_fitness_history, best_individual_history


# GA 核心算法 -- 四波束
def ga_beam_4(pattern_mix_db_target, bit_num):
    # 遗传算法(GA)寻找最优的phaseBit_mix
    ga = RISGeneticAlgorithm(bit_num, 4, 50, 500, 10, 0.1)
    best_individual, best_fitness, best_fitness_history, best_individual_history \
        = ga.run(nRow, nRow, pattern_mix_db_target)
    # logger.info("best_individual:%s" % (best_individual))
    logger.info("Best Fitness=%f" % (best_fitness))
    #
    return best_individual, best_fitness, best_fitness_history, best_individual_history


# GA 核心算法 -- 八波束
def ga_beam_8(pattern_mix_db_target, bit_num):
    # 遗传算法(GA)寻找最优的phaseBit_mix
    ga = RISGeneticAlgorithm(bit_num, 8, 50, 500, 10, 0.1)
    best_individual, best_fitness, best_fitness_history, best_individual_history \
        = ga.run(nRow, nRow, pattern_mix_db_target)
    # logger.info("best_individual:%s" % (best_individual))
    logger.info("Best Fitness=%f" % (best_fitness))
    #
    return best_individual, best_fitness, best_fitness_history, best_individual_history


# 几何分区法 -- 双波束
def main_multi_beam_2(theta1, phi1, theta2, phi2, path_pre, bit_num):
    logger.info("main_multi_beam_2: bit_num=%d, path_pre=%s, " % (bit_num, path_pre))
    logger.info("main_multi_beam_2: theta1=%d, phi1=%d, theta2=%d, phi2=%d, " % (theta1, phi1, theta2, phi2))
    # 目前只支持2bit
    if bit_num > 2:
        logger.error("main_multi_beam_2: bit_num bigger than 2.")
        return
    # 计算单个波束的码阵和指向
    phase1, phaseBit1, pattern1, pattern1_db, x1, y1 = point_2_phase_pattern(theta1, phi1, bit_num)
    phase2, phaseBit2, pattern2, pattern2_db, x2, y2 = point_2_phase_pattern(theta2, phi2, bit_num)
    # pattern1 叠加 pattern2
    # pattern_mix_target = np.maximum(pattern1, pattern2)
    # pattern_mix_db_target = np.abs(pattern_mix_target) / np.max(np.max(np.abs(pattern_mix_target)))
    pattern_mix_db_target = mix_patterns([pattern1_db, pattern2_db])
    # GA
    phase_mix, best_fitness, best_fitness_history, best_individual_history = ga_beam_2(pattern_mix_db_target, bit_num)
    # 相位转换 X bit
    phaseBit_mix, phaseBitDeg_mix = phase_2_bit(phase_mix, bit_num)
    # 计算phase_mix的方向图
    phaseBit_mix = np.deg2rad(phaseBitDeg_mix)
    patternBit_mix = phase_2_pattern(phaseBit_mix)
    #
    # 保存结果
    logger.info("save GA multi-beam 2 result...")
    patternBit_mix_xyz, x, y, z = phase_2_pattern_xyz(phaseBit_mix)
    # 保存图片
    save_img(path_pre + "phase1.jpg", phase1)
    save_img(path_pre + "phase2.jpg", phase2)
    save_img(path_pre + "phaseBit1.jpg", phaseBit1)
    save_img(path_pre + "phaseBit2.jpg", phaseBit2)
    save_img_xyz(path_pre + "pattern1.jpg", np.abs(pattern1), x1, y1)
    save_img_xyz(path_pre + "pattern2.jpg", np.abs(pattern2), x2, y2)
    save_img(path_pre + "phaseBit_mix.jpg", phaseBit_mix)         # GA -- 结果码阵
    save_img(path_pre + "patternBit_mix.jpg", patternBit_mix)     # GA -- 结果码阵方向图
    save_img_xyz(path_pre + "pattern_mix_target.jpg", pattern_mix_db_target, x1, y1)
    save_img_xyz(path_pre + "patternBit_mix_xyz.jpg", np.abs(patternBit_mix_xyz), x, y)
    # 保存相位结果
    save_csv(phase1, path_pre + "phase1.csv")
    save_csv(phase2, path_pre + "phase2.csv")
    save_csv(phaseBit1, path_pre + "phaseBit1.csv")
    save_csv(phaseBit2, path_pre + "phaseBit2.csv")
    save_csv(phaseBit_mix, path_pre + "phaseBit_mix.csv")
    save_csv(pattern_mix_db_target, path_pre + "pattern_mix_target.csv")
    # 保存遗传算法优化结果
    save_line_chart(path_pre + "best_fitness_history.jpg", best_fitness_history,
                    "best_fitness_history", "iteration", "best_fitness", "fitness")
    save_csv([[item] for item in best_fitness_history], path_pre + "best_fitness_history.csv")
    save_csv(best_individual_history, path_pre + "best_individual_history.csv")


# 几何分区法 -- 四波束
def main_multi_beam_4(theta1, phi1, theta2, phi2, theta3, phi3, theta4, phi4, path_pre, bit_num):
    logger.info("main_multi_beam_4: bit_num=%d, path_pre=%s, " % (bit_num, path_pre))
    logger.info("main_multi_beam_4: theta1=%d, phi1=%d, theta2=%d, phi2=%d, theta3=%d, phi3=%d, theta4=%d, phi4=%d"
                % (theta1, phi1, theta2, phi2, theta3, phi3, theta4, phi4))
    # 目前只支持2bit
    if bit_num > 2:
        logger.error("main_multi_beam_N: bit_num bigger than 2.")
        return
    # 计算单个波束的码阵和指向
    phase1, phaseBit1, pattern1, pattern1_db, x1, y1 = point_2_phase_pattern(theta1, phi1, bit_num)
    phase2, phaseBit2, pattern2, pattern2_db, x2, y2 = point_2_phase_pattern(theta2, phi2, bit_num)
    phase3, phaseBit3, pattern3, pattern3_db, x3, y3 = point_2_phase_pattern(theta3, phi3, bit_num)
    phase4, phaseBit4, pattern4, pattern4_db, x4, y4 = point_2_phase_pattern(theta4, phi4, bit_num)
    # pattern1 叠加 pattern2
    # pattern_mix_target = np.maximum(pattern1, pattern2)
    # pattern_mix_db_target = np.abs(pattern_mix_target) / np.max(np.max(np.abs(pattern_mix_target)))
    pattern_mix_db_target = mix_patterns([pattern1_db, pattern2_db])
    # GA
    phase_mix, best_fitness, best_fitness_history, best_individual_history = ga_beam_2(pattern_mix_db_target, bit_num)
    # 相位转换 X bit
    phaseBit_mix, phaseBitDeg_mix = phase_2_bit(phase_mix, bit_num)
    # 计算phase_mix的方向图
    phaseBit_mix = np.deg2rad(phaseBitDeg_mix)
    # 计算phase_mix
    patternBit_mix = phase_2_pattern(phaseBit_mix)
    #
    # 保存结果
    logger.info("save GA multi-beam 4 result...")
    patternBit_mix_xyz, x, y, z = phase_2_pattern_xyz(phaseBit_mix)
    # 保存图片
    save_img(path_pre + "phase1.jpg", phase1)
    save_img(path_pre + "phase2.jpg", phase2)
    save_img(path_pre + "phase3.jpg", phase3)
    save_img(path_pre + "phase4.jpg", phase4)
    save_img(path_pre + "phaseBit1.jpg", phaseBit1)
    save_img(path_pre + "phaseBit2.jpg", phaseBit2)
    save_img(path_pre + "phaseBit3.jpg", phaseBit3)
    save_img(path_pre + "phaseBit4.jpg", phaseBit4)
    save_img_xyz(path_pre + "pattern1.jpg", np.abs(pattern1), x1, y1)
    save_img_xyz(path_pre + "pattern2.jpg", np.abs(pattern2), x2, y2)
    save_img_xyz(path_pre + "pattern3.jpg", np.abs(pattern3), x3, y3)
    save_img_xyz(path_pre + "pattern4.jpg", np.abs(pattern4), x4, y4)
    save_img(path_pre + "phaseBit_mix.jpg", phaseBit_mix)  # GA -- 结果码阵
    save_img(path_pre + "patternBit_mix.jpg", patternBit_mix)  # GA -- 结果码阵方向图
    save_img_xyz(path_pre + "pattern_mix_target.jpg", pattern_mix_db_target, x1, y1)
    save_img_xyz(path_pre + "patternBit_mix_xyz.jpg", np.abs(patternBit_mix_xyz), x, y)
    # 保存相位结果
    save_csv(phase1, path_pre + "phase1.csv")
    save_csv(phase2, path_pre + "phase2.csv")
    save_csv(phase3, path_pre + "phase3.csv")
    save_csv(phase4, path_pre + "phase4.csv")
    save_csv(phaseBit1, path_pre + "phaseBit1.csv")
    save_csv(phaseBit2, path_pre + "phaseBit2.csv")
    save_csv(phaseBit3, path_pre + "phaseBit3.csv")
    save_csv(phaseBit4, path_pre + "phaseBit4.csv")
    save_csv(phaseBit_mix, path_pre + "phase_mix.csv")
    save_csv(pattern_mix_db_target, path_pre + "pattern_mix_target.csv")
    # 保存遗传算法优化结果
    save_line_chart(path_pre + "best_fitness_history.jpg", best_fitness_history,
                    "best_fitness_history", "iteration", "best_fitness", "fitness")
    save_csv([[item] for item in best_fitness_history], path_pre + "best_fitness_history.csv")
    save_csv(best_individual_history, path_pre + "best_individual_history.csv")


def main_multi_beam_8(theta1, phi1, theta2, phi2, theta3, phi3, theta4, phi4,
                      theta5, phi5, theta6, phi6, theta7, phi7, theta8, phi8,
                      path_pre, bit_num):
    logger.info("main_multi_beam_8: bit_num=%d, path_pre=%s, " % (bit_num, path_pre))
    logger.info("main_multi_beam_8: theta1=%d, phi1=%d, theta2=%d, phi2=%d, theta3=%d, phi3=%d, theta4=%d, phi4=%d, "
                "theta5=%d, phi5=%d, theta6=%d, phi6=%d, theta7=%d, phi7=%d, theta8=%d, phi8=%d"
                % (theta1, phi1, theta2, phi2, theta3, phi3, theta4, phi4,
                   theta5, phi5, theta6, phi6, theta7, phi7, theta8, phi8))
    # 目前只支持2bit
    if bit_num > 2:
        logger.error("main_multi_beam_8: bit_num bigger than 2.")
        return
    # 计算单个波束的码阵和指向
    phase1, phaseBit1, pattern1, pattern1_db, x1, y1 = point_2_phase_pattern(theta1, phi1, bit_num)
    phase2, phaseBit2, pattern2, pattern2_db, x2, y2 = point_2_phase_pattern(theta2, phi2, bit_num)
    phase3, phaseBit3, pattern3, pattern3_db, x3, y3 = point_2_phase_pattern(theta3, phi3, bit_num)
    phase4, phaseBit4, pattern4, pattern4_db, x4, y4 = point_2_phase_pattern(theta4, phi4, bit_num)
    phase5, phaseBit5, pattern5, pattern5_db, x5, y5 = point_2_phase_pattern(theta5, phi5, bit_num)
    phase6, phaseBit6, pattern6, pattern6_db, x6, y6 = point_2_phase_pattern(theta6, phi6, bit_num)
    phase7, phaseBit7, pattern7, pattern7_db, x7, y7 = point_2_phase_pattern(theta7, phi7, bit_num)
    phase8, phaseBit8, pattern8, pattern8_db, x8, y8 = point_2_phase_pattern(theta8, phi8, bit_num)
    # pattern1 叠加 pattern2
    # pattern_mix_target = np.maximum(pattern1, pattern2)
    # pattern_mix_db_target = np.abs(pattern_mix_target) / np.max(np.max(np.abs(pattern_mix_target)))
    pattern_mix_db_target = mix_patterns([pattern1_db, pattern2_db])
    # GA
    phase_mix, best_fitness, best_fitness_history, best_individual_history = ga_beam_2(pattern_mix_db_target, bit_num)
    # 相位转换 X bit
    phaseBit_mix, phaseBitDeg_mix = phase_2_bit(phase_mix, bit_num)
    # 计算phase_mix的方向图
    phaseBit_mix = np.deg2rad(phaseBitDeg_mix)
    # 计算phase_mix
    patternBit_mix = phase_2_pattern(phaseBit_mix)
    # 保存结果
    logger.info("save GA multi-beam 8 result...")
    patternBit_mix_xyz, x, y, z = phase_2_pattern_xyz(phaseBit_mix)
    # 保存图片
    save_img(path_pre + "phase1.jpg", phase1)
    save_img(path_pre + "phase2.jpg", phase2)
    save_img(path_pre + "phase3.jpg", phase3)
    save_img(path_pre + "phase4.jpg", phase4)
    save_img(path_pre + "phase5.jpg", phase5)
    save_img(path_pre + "phase6.jpg", phase6)
    save_img(path_pre + "phase7.jpg", phase7)
    save_img(path_pre + "phase8.jpg", phase8)
    save_img(path_pre + "phaseBit1.jpg", phaseBit1)
    save_img(path_pre + "phaseBit2.jpg", phaseBit2)
    save_img(path_pre + "phaseBit3.jpg", phaseBit3)
    save_img(path_pre + "phaseBit4.jpg", phaseBit4)
    save_img(path_pre + "phaseBit5.jpg", phaseBit5)
    save_img(path_pre + "phaseBit6.jpg", phaseBit6)
    save_img(path_pre + "phaseBit7.jpg", phaseBit7)
    save_img(path_pre + "phaseBit8.jpg", phaseBit8)
    save_img_xyz(path_pre + "pattern1.jpg", np.abs(pattern1), x1, y1)
    save_img_xyz(path_pre + "pattern2.jpg", np.abs(pattern2), x2, y2)
    save_img_xyz(path_pre + "pattern3.jpg", np.abs(pattern3), x3, y3)
    save_img_xyz(path_pre + "pattern4.jpg", np.abs(pattern4), x4, y4)
    save_img_xyz(path_pre + "pattern5.jpg", np.abs(pattern5), x5, y5)
    save_img_xyz(path_pre + "pattern6.jpg", np.abs(pattern6), x6, y6)
    save_img_xyz(path_pre + "pattern7.jpg", np.abs(pattern7), x7, y7)
    save_img_xyz(path_pre + "pattern8.jpg", np.abs(pattern8), x8, y8)
    save_img(path_pre + "phaseBit_mix.jpg", phaseBit_mix)  # GA -- 结果码阵
    save_img(path_pre + "patternBit_mix.jpg", patternBit_mix)  # GA -- 结果码阵方向图
    save_img_xyz(path_pre + "pattern_mix_target.jpg", pattern_mix_db_target, x1, y1)
    save_img_xyz(path_pre + "patternBit_mix_xyz.jpg", np.abs(patternBit_mix_xyz), x, y)
    # 保存相位结果
    save_csv(phase1, path_pre + "phase1.csv")
    save_csv(phase2, path_pre + "phase2.csv")
    save_csv(phase3, path_pre + "phase3.csv")
    save_csv(phase4, path_pre + "phase4.csv")
    save_csv(phase5, path_pre + "phase5.csv")
    save_csv(phase6, path_pre + "phase6.csv")
    save_csv(phase7, path_pre + "phase7.csv")
    save_csv(phase8, path_pre + "phase8.csv")
    save_csv(phaseBit1, path_pre + "phaseBit1.csv")
    save_csv(phaseBit2, path_pre + "phaseBit2.csv")
    save_csv(phaseBit3, path_pre + "phaseBit3.csv")
    save_csv(phaseBit4, path_pre + "phaseBit4.csv")
    save_csv(phaseBit5, path_pre + "phaseBit5.csv")
    save_csv(phaseBit6, path_pre + "phaseBit6.csv")
    save_csv(phaseBit7, path_pre + "phaseBit7.csv")
    save_csv(phaseBit8, path_pre + "phaseBit8.csv")
    save_csv(phaseBit_mix, path_pre + "phaseBit_mix.csv")
    save_csv(pattern_mix_db_target, path_pre + "pattern_mix_target.csv")
    # 保存遗传算法优化结果
    save_line_chart(path_pre + "best_fitness_history.jpg", best_fitness_history,
                    "best_fitness_history", "iteration", "best_fitness", "fitness")
    save_csv([[item] for item in best_fitness_history], path_pre + "best_fitness_history.csv")
    save_csv(best_individual_history, path_pre + "best_individual_history.csv")


# ======================================================= main 主方法 ===============================================
def main_multi_ga():
    # 基于GA的方法: 主函数
    # 测试方法
    #
    # 几何分区法: 主函数
    main_multi_beam_2(30, 0, 30, 90,
                      "../files/multi-beam/1bit/GA/2-(30,0,30,90)/", 1)
    main_multi_beam_2(30, 0, 30, 180,
                      "../files/multi-beam/1bit/GA/2-(30,0,30,180)/", 1)
    main_multi_beam_4(30, 0, 30, 60, 30, 120, 30, 180,
                      "../files/multi-beam/1bit/GA/4-(30,0,30,60,30,120,30,180)/", 1)
    main_multi_beam_4(30, 0, 30, 90, 30, 180, 30, 270,
                      "../files/multi-beam/1bit/GA/4-(30,0,30,90,30,180,30,270)/", 1)
    main_multi_beam_8(30, 0, 30, 45, 30, 90, 30, 135, 30, 180, 30, 225, 30, 270, 30, 315,
                      "../files/multi-beam/1bit/GA/8-(30,45step)/", 1)
    #
    # main_multi_beam_2(30, 0, 30, 90,
    #                   "../files/multi-beam/2bit/GA/2-(30,0,30,90)/", 2)
    # main_multi_beam_2(30, 0, 30, 180,
    #                   "../files/multi-beam/2bit/GA/2-(30,0,30,180)/", 2)
    # main_multi_beam_4(30, 0, 30, 60, 30, 120, 30, 180,
    #                   "../files/multi-beam/2bit/GA/4-(30,0,30,60,30,120,30,180)/", 2)
    # main_multi_beam_4(30, 0, 30, 90, 30, 180, 30, 270,
    #                   "../files/multi-beam/2bit/GA/4-(30,0,30,90,30,180,30,270)/", 2)
    # main_multi_beam_8(30, 0, 30, 45, 30, 90, 30, 135, 30, 180, 30, 225, 30, 270, 30, 315,
    #                   "../files/multi-beam/2bit/GA/8-(30,45step)/", 2)





if __name__ == '__main__':
    logger.info("1bit-RIS-multi-beam: GA method")
    main_multi_ga()